﻿using System;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;

public static class NewFeaturesXmlParseProc
{
    public static void Parse(XmlNode root_node, ref NewFeatureList features)
    {
        XmlNodeList node_list = root_node.ChildNodes;
        Dictionary<int, bool> mb = new Dictionary<int, bool>();
        for (int i = 0; i < node_list.Count; ++i)
        {
            XmlNewFeatureData data = new XmlNewFeatureData();
            XmlNode node = node_list[i] as XmlNode;
            string name = node.Name;
            if (name == "feature")
            {
                var id = XmlConvert.ToInt32(node.Attributes["id"].Value);
                if( !mb.ContainsKey(id) )
                {
                    if (!ParseFeatureNode(node, data))
                    {
                        features = null;
                        return;
                    }
                    mb.Add(data.id, true);
                    features.item_list.Add(data);
                }
            }
        }
    }

    private static bool ParseFeatureNode(XmlNode node, XmlNewFeatureData data)
    {
        data.id = XmlConvert.ToInt32(node.Attributes["id"].Value);
        data.level = XmlConvert.ToInt32(node.Attributes["level"].Value);
        data.fly_show = XmlConvert.ToBoolean(node.Attributes["fly_show"].Value);
        data.enable = XmlConvert.ToBoolean(node.Attributes["enable"].Value);
        if (node.Attributes["callback_event_type"] != null)
        {
            data.callback_event_type = XmlConvert.ToInt32(node.Attributes["callback_event_type"].Value);
        }

        if (node.Attributes["on_ground_hide"] != null)
        {
            data.on_ground_hide = XmlConvert.ToBoolean(node.Attributes["on_ground_hide"].Value);
        }
        else
        {
            data.on_ground_hide = false;
        }

        XmlNodeList children = node.ChildNodes as XmlNodeList;
        for (int i = 0; i < children.Count; ++i)
        {
            XmlNode child = children[i] as XmlNode;
            if (child.Name == "ui")
            {
                if (!ParseFeatureUseCaseNode(child, data.ui_data))
                {
                    return false;
                }
            }
            else if (child.Name == "ingame")
            {
                if (!ParseFeatureUseCaseNode(child, data.ingame_data))
                {
                    return false;
                }
            }
        }
        if (node.Attributes["special_show"] != null)
        {
            data.special_show = XmlConvert.ToBoolean(node.Attributes["special_show"].Value);
        }
        return true;
    }

    private static bool ParseFeatureUseCaseNode(XmlNode node, XmlFeatureUseCaseData data)
    {
        data.start_section = node.Attributes["start_section"].Value;
        data.pos_offset = node.Attributes["pos_offset"].Value;
        if (node.Attributes["rotation"] != null)
        {
            data.rotation = node.Attributes["rotation"].Value;
        }
        data.ui_camera_id = XmlConvert.ToInt32(node.Attributes["ui_camera_id"].Value);
        if (node.Attributes["need_hide_first_frame"] != null)
        {
            data.need_hide_first_frame = bool.Parse(node.Attributes["need_hide_first_frame"].Value);
        }
        if (null != node.Attributes["hide_pet"])
        {
            string featureStr = node.Attributes["hide_pet"].Value;
            data.hide_pet_level_list.Clear();
            if (!string.IsNullOrEmpty(featureStr))
            {
                string[] strArray = featureStr.Split(',');
                for (int i = 0; i < strArray.Length; i++)
                {
                    data.hide_pet_level_list.Add(int.Parse(strArray[i]));
                }
            }
        }
        XmlNodeList children = node.ChildNodes as XmlNodeList;
        bool isContainsBlobal = false;
        for (int i = 0; i < children.Count; ++i)
        {
            XmlNode child = children[i] as XmlNode;
            if (child.Name == "global_section")
            {
                isContainsBlobal = true;
                ParseFeatureSectionNode(child, data.global_section);
            }
            if (child.Name == "data_config_section")
            {
                ParseDataSectionNode(child, data.data_config_section);
            }
            else if (child.Name == "section")
            {
                XmlFeatureSectionData section_data = new XmlFeatureSectionData();
                ParseFeatureSectionNode(child, section_data);
                data.section_list.Add(section_data);
            }
        }
        return isContainsBlobal;
    }

    private static void ParseDataSectionNode(XmlNode node, XmlFeatureDataConfigSection data)
    {
        XmlNodeList children = node.ChildNodes as XmlNodeList;
        for (int i = 0; i < children.Count; ++i)
        {
            XmlNode child = children[i] as XmlNode;
            if (child.Name == "behavior")
            {
                string key = child.Attributes["key"].Value;
                FeatureDataConfigType type = (FeatureDataConfigType)Enum.Parse(typeof(FeatureDataConfigType), key);
                if (!data.m_data.ContainsKey((int)type))
                {
                    data.m_data.Add((int)type, child.Attributes["value"].Value);
                }
            }
        }
    }

    private static void ParseFeatureSectionNode(XmlNode node, XmlFeatureSectionData data)
    {
        data.type = node.Attributes["type"].Value;
        data.next_section = node.Attributes["next_section"].Value;
        if (node.Attributes["next_feature_id"] != null && node.Attributes["next_feature_id"].Value != string.Empty)
        {
            data.next_featureID = XmlConvert.ToInt32(node.Attributes["next_feature_id"].Value);
        }

        data.show_time = XmlConvert.ToInt32(node.Attributes["show_time"].Value);
        data.param = node.Attributes["param"].Value;
        XmlNodeList children = node.ChildNodes as XmlNodeList;
        for (int i = 0; i < children.Count; ++i)
        {
            XmlNode child = children[i] as XmlNode;
            if (child.Name == "behavior")
            {
                XmlFeatureBehaviorData behavior_data = new XmlFeatureBehaviorData();
                ParseFeatureBehaviorNode(child, behavior_data);
                data.behavior_list.Add(behavior_data);
            }
        }
    }

    private static void ParseFeatureBehaviorNode(XmlNode node, XmlFeatureBehaviorData data)
    {
        data.start_time = XmlConvert.ToInt32(node.Attributes["start_time"].Value);
        data.end_time = XmlConvert.ToInt32(node.Attributes["end_time"].Value);
        data.type = node.Attributes["type"].Value;
        data.param = node.Attributes["param"].Value;
        data.param2 = node.Attributes["param2"].Value;
        data.param3 = node.Attributes["param3"].Value;
        data.param4 = node.Attributes["param4"].Value;
        if (node.Attributes["param5"] != null)
        {
            data.param5 = node.Attributes["param5"].Value;
        }
        if (node.Attributes["param6"] != null)
        {
            data.param6 = node.Attributes["param6"].Value;
        }
        if (data.type == "link")
        {
            XmlNodeList children = node.ChildNodes as XmlNodeList;
            for (int i = 0; i < children.Count; ++i)
            {
                XmlNode child = children[i] as XmlNode;
                if (child.Name == "link")
                {
                    XmlFeatureLinkData link_data = new XmlFeatureLinkData();
                    ParseFeatureLinkNode(child, link_data);
                    data.link_effect_list.Add(link_data);
                }
            }
        }
        else if (data.type == "cloth_anim")
        {
            XmlNodeList children = node.ChildNodes as XmlNodeList;
            for (int i = 0; i < children.Count; ++i)
            {
                XmlNode child = children[i] as XmlNode;
                if (child.Name == "reset_cloth_anim")
                {
                    XmlFeatureResetClothAnimData animData = new XmlFeatureResetClothAnimData();
                    ParseFeatureResetAnimNode(child, animData);
                    data.reset_cloth_anim_list.Add(animData);
                }
            }
        }
    }

    private static void ParseFeatureLinkNode(XmlNode node, XmlFeatureLinkData data)
    {
        data.id = node.Attributes["id"].Value;
        data.save = XmlConvert.ToBoolean(node.Attributes["save"].Value);
        data.pos = node.Attributes["pos"].Value;
        data.rotation = node.Attributes["rotation"].Value;
        if (node.Attributes["loop"] != null)
        {
            data.loop = XmlConvert.ToInt32(node.Attributes["loop"].Value);
        }
    }

    private static void ParseFeatureResetAnimNode(XmlNode node, XmlFeatureResetClothAnimData data)
    {
        data.m_SectionType = node.Attributes["section_type"].Value;
        data.m_IsLast = XmlConvert.ToBoolean(node.Attributes["is_last"].Value);
        data.m_AnimName = node.Attributes["anim_name"].Value;
        if (node.Attributes["is_last_fly"] != null)
        {
            data.m_IsLastOnFly = XmlConvert.ToBoolean(node.Attributes["is_last_fly"].Value);
        }
        if (node.Attributes["anim_name_fly"] != null)
        {
            data.m_AnimNameOnFly = node.Attributes["anim_name_fly"].Value;
        }

        if (node.Attributes["next_feature_id"] != null && node.Attributes["next_feature_id"].Value != string.Empty)
        {
            data.m_NextFeatureID = XmlConvert.ToInt32(node.Attributes["next_feature_id"].Value);
        }
    }

}
